package com.dingreading.cloud.admin.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dingreading.cloud.admin.dto.HeadStaffDto;
import com.dingreading.cloud.admin.entity.AdminMenus;
import com.dingreading.cloud.admin.entity.AdminRoleStaff;
import com.dingreading.cloud.admin.entity.AdminRoles;
import com.dingreading.cloud.admin.entity.HeadStaff;
import com.dingreading.cloud.admin.service.*;
import com.dingreading.cloud.admin.util.PasswordUtil;
import com.dingreading.cloud.admin.util.TreeJsonUtil;
import com.dingreading.cloud.admin.util.jwt.JwtHelper;
import com.dingreading.cloud.admin.util.redis.RedisService;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.util.*;
import com.google.common.collect.Lists;
import com.mybatisflex.core.paginate.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/system/headStaff")
@Api(tags = "总部-总部员工管理相关")
public class HeadStaffController {

    @Resource
    protected HeadStaffService headStaffService;
    @Resource
    protected AdminButtonService buttonService;
    @Resource
    protected AdminRoleStaffService roleStaffService;
    @Resource
    protected AdminMenusService menusService;
    @Resource
    protected AdminRolesService rolesService;
    @Resource
    protected RedisService redisService;


    @ApiOperation(value = "总部员工列表")
    @PostMapping(value = "/pageList", produces = "application/json; charset=UTF-8")
    public R<Object> pageList(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "分页公共类") PageUtil pageUtil,
            @ApiParam(value = "是否禁用 1.启用 0.禁用") @RequestParam(value = "enabled", required = false) Integer enabled,
            @ApiParam(value = "手机") @RequestParam(value = "phone", required = false) String phone,
            @ApiParam(value = "姓名") @RequestParam(value = "userName", required = false) String userName,
            @ApiParam(value = "角色id") @RequestParam(value = "roleId", required = false) Long roleId
    ) {
        Page<HeadStaffDto> page = headStaffService.pageList(pageUtil, enabled, phone, userName);

        List<HeadStaffDto> list = page.getRecords();
        if (CollectionUtils.isNotEmpty(list) && roleId != null && roleId > 0) {
            List<String> uids = list.stream().map(HeadStaffDto::getUid).collect(Collectors.toList());

            List<String> uidList = roleStaffService.getByRoleIdAndStaffUid(roleId, uids);

            for (HeadStaffDto staff : list) {
                staff.setAddStatus(uidList.contains(staff.getUid()) ? 1 : 0);
            }
        }

        PageBeanDto dto = new PageBeanDto();
        dto.setList(list);
        dto.setTotal(page.getTotalRow());
        return R.ok(dto);
    }


    @ApiOperation(value = "编辑总部员工信息")
    @PostMapping(value = "/editHeadStaff", produces = "application/json; charset=UTF-8")
    public R<Object> editHeadStaff(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "员工id") @RequestParam(value = "id", required = false) Long id,
            @ApiParam(value = "姓名") @RequestParam(value = "userName") String userName,
            @ApiParam(value = "手机号") @RequestParam(value = "phone") String phone
    ) {
        // 判断手机是否存在账号
        boolean b = headStaffService.havePhone(id, phone);
        if (b)
            return R.fail("手机账号已注册，不能操作");

        // 判断新增修改
        HeadStaff data = null;
        if (id == null || id <= 0) {
            data = new HeadStaff();
            // 设置总部员工uid
            data.setUid("HE" + KitUtil.getUuid());
            data.setUserName(userName);
            data.setPhone(phone);
            //新建设置密码
            //设置随机密码
            String password = KitUtil.getRandomPwdStr(6);
            PasswordUtil.createPassword(data, password);
            data.setEnabled(1);
            headStaffService.saveOrUpdate(data);

            String msg = "账号：" + phone + "，密码：" + password;
            return R.ok(msg);
        } else {
            data = headStaffService.getById(id);
            if (data == null)
                return R.fail("总部员工获取失败");
            if (userName != null)
                data.setUserName(userName);
            if (phone != null)
                data.setPhone(phone);
            headStaffService.saveOrUpdate(data);
            return R.ok();
        }

    }


    @ApiOperation(value = "删除总部员工")
    @DeleteMapping(value = "/dropBean", produces = "application/json; charset=UTF-8")
    public R<Object> dropBean(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "总部员工id") @RequestParam(value = "id") Long id
    ) {
        headStaffService.removeById(id);
        return R.ok();
    }


    @ApiOperation(value = "总部员工修改状态")
    @PostMapping(value = "/updateStatus", produces = "application/json; charset=UTF-8")
    public R<Object> updateStatus(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "总部员工id") @RequestParam(value = "id") Long id,
            @ApiParam(value = "状态：-1.禁用 1.正常") @RequestParam(value = "status") Integer status) {
        this.headStaffService.updateStatus(status, Lists.newArrayList(id));
        return R.ok();
    }


    @ApiOperation(value = "总部员工修改账号密码")
    @PostMapping(value = "/updatePassword", produces = "application/json; charset=UTF-8")
    public R<Object> updatePassword(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "新密码") @RequestParam(value = "newPass") String newPass,
            @ApiParam(value = "确认新密码") @RequestParam(value = "confirmPass") String confirmPass
    ) {
        HeadStaff headStaff = headStaffService.getByUid(headStaffUid);
        // 用户信息及原密码判断是否可以修改
        if (headStaff == null) return R.fail("员工获取失败");
        if (newPass.length() < 6) return R.fail("新密码必须大于6位");
        if (!newPass.equals(confirmPass)) return R.fail("两次输入的新密码不一样");

        // 修改密码
        PasswordUtil.resetPassword(headStaff, newPass);
        headStaffService.saveOrUpdate(headStaff);

        String msg = "账号：" + headStaff.getPhone() + "，密码：" + newPass;
        return R.ok(msg);
    }


    @ApiOperation(value = "重置账号密码")
    @PostMapping(value = "/resetPassword", produces = "application/json; charset=UTF-8")
    public R<Object> resetPassword(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "总部员工id") @RequestParam(value = "id") Long id
    ) {
        HeadStaff headStaff = headStaffService.getById(id);
        // 用户信息及原密码判断是否可以修改
        if (headStaff == null) return R.fail("员工获取失败");

        // 修改密码
        String password = KitUtil.getRandomPwdStr(6);
        PasswordUtil.resetPassword(headStaff, password);
        headStaffService.saveOrUpdate(headStaff);

        String msg = "账号：" + headStaff.getPhone() + "，密码：" + password;
        return R.ok(msg);
    }


    @ApiOperation(value = "根据id获取信息")
    @PostMapping(value = "/getById", produces = "application/json; charset=UTF-8")
    public R<Object> getById(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "门店员工id") @RequestParam(value = "id") Long id
    ) {
        HeadStaff headStaff = headStaffService.getById(id);
        return R.ok(headStaff);
    }


    @ApiOperation(value = "获取可用的员工")
    @PostMapping(value = "/getUseList", produces = "application/json; charset=UTF-8")
    public R<Object> getUseList(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName
    ) {
        List<HeadStaff> list = headStaffService.getUseList();
        return R.ok(list);
    }

    @ApiOperation(value = "获取图片验证码")
    @GetMapping(value = "/getPicCode", produces = "application/json; charset=UTF-8")
    public void getPicCode(
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        //获取session的Id
        HttpSession session = request.getSession();
        String sessionId = session.getId();
        //判断session是不是新创建的
//        if (session.isNew()) {
//            System.out.println("session创建成功，session的id是：" + sessionId);
//        } else {
//            System.out.println("服务器已经存在该session了，session的id是：" + sessionId);
//        }
        // 设置响应的类型格式为图片格式
        response.setContentType("image/jpeg");
        // 禁止图像缓存。
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");
        //实例生成验证码对象
        SCaptcha instance = new SCaptcha();
        String code = instance.getCode();
        if (StringUtils.isNotBlank(code)) {
            //将验证码存入redis
            redisService.set("pic_code_" + sessionId, code, 120);
            //向页面输出验证码图片
            instance.write(response.getOutputStream());
        }
    }


    @ApiOperation(value = "总部员工登录-密码")
    @PostMapping(value = "/login", produces = "application/json; charset=UTF-8")
    public R<Object> login(
            HttpServletRequest request,
            @ApiParam(value = "手机") @RequestParam(value = "phone") String phone,
            @ApiParam(value = "密码") @RequestParam(value = "password") String password,
            @ApiParam(value = "验证码") @RequestParam(value = "code") String code
    ) {
        if (StringUtils.isBlank(phone))
            return R.fail("请填写登录账号");
        if (StringUtils.isBlank(password))
            return R.fail("请填写登录密码");
        if (StringUtils.isBlank(code))
            return R.fail("请填写验证码");

        // 验证验证码
        HttpSession session = request.getSession();
        //获取session的Id
        String redisKey = "pic_code_" + session.getId();
        String redisPicCode = redisService.getValue(redisKey);
        if (StringUtils.isBlank(redisPicCode)) {
            return R.fail("验证码已失效");
        } else {
            String upperSessionCode = redisPicCode.toUpperCase();
            String upperCode = code.toUpperCase();
            if (!upperSessionCode.equals(upperCode))
                return R.fail("验证码错误");
        }

        // 判断账号是否存在
        HeadStaffDto staff = headStaffService.getByPhone(phone);
        if (staff == null)
            return R.fail(4016, "账号不存在");

        // 判断密码是否正确
        String decryptionPassword = PasswordUtil.decryptionPassword(staff.getEncodedPwd(), staff.getPwdSalt());
        if (!decryptionPassword.equals(password)) {
            return R.fail("请输入正确密码");
        }
        // 判断账号状态
        if (!staff.getEnabled().equals(1)) {
            return R.fail("该账号已禁用");
        }
        List<String> identifyList = roleStaffService.identifyListByStaffUid(staff.getUid());
        if (CollectionUtils.isEmpty(identifyList))
            return R.fail("未分配角色权限");

        // 登录时间
        String loginTime = DateUtil.getNowDatetimeStr();
        // 生成token
        String token = JwtHelper.getHeadToken(staff.getUid(), loginTime);
        boolean b = headStaffService.updateLoginInfo(staff.getUid(), token, loginTime);
        if (!b)
            return R.fail("更新登录信息失败");

        staff.setIdentifyList(identifyList);
        staff.setLastLoginTime(loginTime);
        staff.setToken(token);
        redisService.delete(redisKey);
        // 更新缓存信息
        redisService.set(RedisParam.HEAD_STAFF + staff.getUid(), JsonUtil.toJsonString(staff), RedisParam.HOUR_TIME);

        return R.ok(staff);
    }

    @ApiOperation(value = "获取员工的菜单和按钮权限")
    @PostMapping(value = "/getMenuAndButton", produces = "application/json; charset=UTF-8")
    public R<Object> getMenuAndButton(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName
    ) {
        List<AdminRoleStaff> roleStaffList = roleStaffService.listByHeadStaffUid(headStaffUid);
        if (CollectionUtils.isEmpty(roleStaffList))
            return R.fail("未分配角色权限");
        List<Long> roleIds = roleStaffList.stream().map(AdminRoleStaff::getRoleId).collect(Collectors.toList());
        // 角色信息
        List<AdminRoles> roles = rolesService.listByIds(roleIds);
        if (roles == null)
            return R.fail("用户的角色获取失败");

        // 获取菜单权限
        JSONArray treeJson = new JSONArray();
        List<AdminMenus> menusList = menusService.listByRoleIdAndEnabled(roleIds, 1);
        if (CollectionUtils.isNotEmpty(menusList)) {
            treeJson = TreeJsonUtil.createAdminMenusTreeJson(menusList);
        }

        // 获取按钮权限
        List<String> buttonList = buttonService.listByRoleId(roleIds);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("menus", treeJson);
        jsonObject.put("buttons", buttonList);
        jsonObject.put("role", roles);

        return R.ok(jsonObject);
    }

    @ApiOperation(value = "获取运营人员")
    @PostMapping(value = "/getOperateStaffs", produces = "application/json; charset=UTF-8")
    public R<Object> getOperateStaffs(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName
    ) {
        List<HeadStaff> list = headStaffService.getByRoleIdIn(Lists.newArrayList(7L, 9L, 17L));

        return R.ok(list);
    }

    @ApiOperation(value = "根据id获取信息-测试")
    @GetMapping(value = "/get", produces = "application/json; charset=UTF-8")
    public R<Object> get(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "门店员工id") @RequestParam(value = "id") Long id
    ) {
        HeadStaff headStaff = headStaffService.getById(id);
        return R.ok(headStaff);
    }

}
